package com.chaos.meta.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author:  naicha
 * @date:  2020年06月12日
 * @description: socket cache
 */
@Component
@Slf4j
@ServerEndpoint("/websocket/{userId}")
public class WebSocketServer {

    /**
     *  与某个客户端的连接对话，需要通过它来给客户端发送消息
     */
    private Session session;
    /**
     * 标识当前连接客户端的用户Id
     */
    private String userId;

    /**
     *  用于存所有的连接服务的客户端，这个对象存储是安全的
     */
    private static ConcurrentHashMap<String, WebSocketServer> webSocketMap = new ConcurrentHashMap<>();

//    /**
//     *  解决socket无法注入bean的问题
//     */
//    private static WorldServiceForViewer sServerForViewer;
//    @Autowired
//    public void setChatService(WorldServiceForViewer sServerForViewer) {
//        WebSocketServer.sServerForViewer = sServerForViewer;
//    }

    /**
     *  userId，如果需要指定发送，需要指定发送通过userId来区分
     */
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "userId") String userId){
    	this.session = session;
    	// 云服务socket发送的userId实际为X-XSRF-TOKEN的值
        this.userId = userId;
        webSocketMap.put(userId, this);
    	log.info(String.format("Session with ID %s of userId %s is opened.", session.getId(), userId));
    }

    @OnClose
    public void onClose(){
        webSocketMap.remove(userId);
    }

    @OnError
    public void onerror(Session session, Throwable throwable)
    {
        log.info("socket communicate exception.");
    }

    @OnMessage
    public void onMessage(Session session, String message){
    	JSONObject messageJson;
    	try {
    		messageJson = JSON.parseObject(message);
    	}catch(Exception e) {
    		return;
    	}

        String userId = messageJson.getString("userId");

        if (null != userId)
        {
            webSocketMap.put(userId,this);
        }

        CompletableFuture.runAsync(()->{
        });
    }

    /**
     * 指定发送
     * @param userId
     * @param message
     */
    public void appointSending(String userId, String message)
    {
        try {
            webSocketMap.get(userId).session.getBasicRemote().sendText(message);
        }catch (Exception e){
            log.error(String.format("fail to sendMessage, userId is %s", userId));
        }
    }
}
